﻿//  -------------------- iSharePoint -------------------- //
// 
//  Company:	IT Complex, LLC
//  Project:	Smart.Common
//  File name:	CamlQueryBuilderConditionGroup.cs
//  Developer:	Solomatov Igor
//  Created:	15.04.2012
// 
//  -------------------- iSharePoint -------------------- //

using System;
using System.Linq;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;

namespace Smart.Common.Entities
{
	/// <summary>
	/// Group of condition items
	/// </summary>
	public class CamlQueryBuilderConditionGroup<TExecutorType> : CamlQueryBuilderItemGroupGroupable<TExecutorType>, IQueryBuilderConditionGroup<TExecutorType>
		where TExecutorType : class
	{
		/// <summary>
		/// Parent Group
		/// </summary>
		public IQueryBuilderConditionGroup<TExecutorType> Parent
		{
			get { return Group as CamlQueryBuilderConditionGroup<TExecutorType>; }
		}

		public CamlQueryBuilderConditionGroup(string op, bool groupChildren, bool groupAlways)
			: base(op, groupChildren, groupAlways)
		{
		}

		#region Universal reflected methods

		public virtual Func<string, CamlQueryBuilderConditionGroup<TExecutorType>> GetMethod(FilterCondition op)
		{
			var mi = GetType().GetMethod(op.ToString(), new[] { typeof(string) });

			if (mi == null)
				return null;

			return
				field => mi.Invoke(this, new object[] { field }) as CamlQueryBuilderConditionGroup<TExecutorType>;
		}

		public virtual Func<string, object, CamlQueryBuilderConditionGroup<TExecutorType>> GetMethod(FilterCondition op, Type vt)
		{
			var mi = GetType().GetMethod(op.ToString(), new[] { typeof(string), vt });

			if (mi == null)
				return null;

			return
				(field, value) => mi.Invoke(this, new[] { field, value }) as CamlQueryBuilderConditionGroup<TExecutorType>;
		}

		public virtual Func<string, object, object, CamlQueryBuilderConditionGroup<TExecutorType>> GetMethod(FilterCondition op, Type vt1, Type vt2)
		{
			var mi = GetType().GetMethod(op.ToString(), new[] { typeof(string), vt1, vt2 });

			if (mi == null)
				return null;

			return
				(field, value1, value2) => mi.Invoke(this, new[] { field, value1, value2 }) as CamlQueryBuilderConditionGroup<TExecutorType>;
		}

		public virtual IQueryBuilderConditionGroup<TExecutorType> Filter(string field, FilterCondition op)
		{
			var method = GetMethod(op);

			if (method == null)
				throw new NotSupportedException();

			return method(field);
		}

		public virtual IQueryBuilderConditionGroup<TExecutorType> Filter(string field, FilterCondition op, object value)
		{
			var method = GetMethod(op, (value == null ? typeof(string) : value.GetType()));

			if (method == null)
				throw new NotSupportedException();

			return method(field, value);
		}

		public virtual IQueryBuilderConditionGroup<TExecutorType> Filter(string field, FilterCondition op, object value1, object value2)
		{
			var method = GetMethod(op, (value1 == null ? typeof(string) : value1.GetType()), (value2 == null ? typeof(string) : value2.GetType()));

			if (method == null)
				throw new NotSupportedException();

			return method(field, value1, value2);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Filter(Guid fieldId, FilterCondition op)
		{
			return Filter(fieldId.ToString(), op);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Filter(Guid fieldId, FilterCondition op, object value)
		{
			return Filter(fieldId.ToString(), op, value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Filter(Guid fieldId, FilterCondition op, object value1, object value2)
		{
			return Filter(fieldId.ToString(), op, value1, value2);
		}

		#endregion

		#region Generics

		/// <summary>
		/// Adds generic condition
		/// </summary>
		public CamlQueryBuilderConditionGroup<TExecutorType> Condition(string field, string op, string valueType, string value)
		{
			AddItem(new CamlQueryBuilderConditionItem<TExecutorType>(field, op, valueType, value));

			return this;
		}

		/// <summary>
		/// Adds generic condition
		/// </summary>
		public CamlQueryBuilderConditionGroup<TExecutorType> Condition(string field, string op, int value)
		{
			AddItem(new CamlQueryBuilderConditionItem<TExecutorType>(field, op, "Integer", value.ToString(H.En)));

			return this;
		}

		/// <summary>
		/// Adds generic condition
		/// </summary>
		public CamlQueryBuilderConditionGroup<TExecutorType> Condition(string field, string op, double value)
		{
			AddItem(new CamlQueryBuilderConditionItem<TExecutorType>(field, op, "Number", value.ToString(H.En.NumberFormat)));

			return this;
		}

		/// <summary>
		/// Adds generic condition
		/// </summary>
		public CamlQueryBuilderConditionGroup<TExecutorType> Condition(string field, string op, bool value)
		{
			AddItem(new CamlQueryBuilderConditionItem<TExecutorType>(field, op, "Boolean", (value ? "1" : "0")));

			return this;
		}

		/// <summary>
		/// Adds generic condition
		/// </summary>
		public CamlQueryBuilderConditionGroup<TExecutorType> Condition(string field, string op, DateTime value)
		{
			AddItem(new CamlQueryBuilderConditionItem<TExecutorType>(field, op, "DateTime", SPUtility.CreateISO8601DateTimeFromSystemDateTime(value)));

			return this;
		}

		/// <summary>
		/// Adds generic condition
		/// </summary>
		public CamlQueryBuilderConditionGroup<TExecutorType> Condition(string field, string op, string value)
		{
			AddItem(new CamlQueryBuilderConditionItem<TExecutorType>(field, op, "Text", value));

			return this;
		}

		/// <summary>
		/// Adds generic statement
		/// </summary>
		public CamlQueryBuilderConditionGroup<TExecutorType> Statement(string field, string op, string statement)
		{
			AddItem(new CamlQueryBuilderStatementItem<TExecutorType>(field, string.Empty, op, statement));

			return this;
		}

		#endregion

		#region Eq

		public IQueryBuilderConditionGroup<TExecutorType> Eq(string field, string value)
		{
			return Condition(field, "Eq", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Eq(string field, int value)
		{
			return Condition(field, "Eq", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Eq(string field, double value)
		{
			return Condition(field, "Eq", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Eq(string field, bool value)
		{
			return Condition(field, "Eq", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Eq(string field, DateTime value)
		{
			return Condition(field, "Eq", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Eq(Guid fieldId, string value)
		{
			return Eq(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Eq(Guid fieldId, int value)
		{
			return Eq(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Eq(Guid fieldId, double value)
		{
			return Eq(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Eq(Guid fieldId, bool value)
		{
			return Eq(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Eq(Guid fieldId, DateTime value)
		{
			return Eq(fieldId.ToString(), value);
		}

		#endregion

		#region Neq

		public IQueryBuilderConditionGroup<TExecutorType> Neq(string field, string value)
		{
			return Condition(field, "Neq", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Neq(string field, int value)
		{
			return Condition(field, "Neq", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Neq(string field, double value)
		{
			return Condition(field, "Neq", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Neq(string field, bool value)
		{
			return Condition(field, "Neq", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Neq(string field, DateTime value)
		{
			return Condition(field, "Neq", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Neq(Guid fieldId, string value)
		{
			return Neq(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Neq(Guid fieldId, int value)
		{
			return Neq(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Neq(Guid fieldId, double value)
		{
			return Neq(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Neq(Guid fieldId, bool value)
		{
			return Neq(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Neq(Guid fieldId, DateTime value)
		{
			return Neq(fieldId.ToString(), value);
		}

		#endregion

		#region Geq

		public IQueryBuilderConditionGroup<TExecutorType> Geq(string field, string value)
		{
			return Condition(field, "Geq", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Geq(string field, int value)
		{
			return Condition(field, "Geq", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Geq(string field, double value)
		{
			return Condition(field, "Geq", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Geq(string field, bool value)
		{
			return Condition(field, "Geq", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Geq(string field, DateTime value)
		{
			return Condition(field, "Geq", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Geq(Guid fieldId, string value)
		{
			return Geq(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Geq(Guid fieldId, int value)
		{
			return Geq(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Geq(Guid fieldId, double value)
		{
			return Geq(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Geq(Guid fieldId, bool value)
		{
			return Geq(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Geq(Guid fieldId, DateTime value)
		{
			return Geq(fieldId.ToString(), value);
		}

		#endregion

		#region Leq

		public IQueryBuilderConditionGroup<TExecutorType> Leq(string field, string value)
		{
			return Condition(field, "Leq", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Leq(string field, int value)
		{
			return Condition(field, "Leq", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Leq(string field, double value)
		{
			return Condition(field, "Leq", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Leq(string field, bool value)
		{
			return Condition(field, "Leq", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Leq(string field, DateTime value)
		{
			return Condition(field, "Leq", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Leq(Guid fieldId, string value)
		{
			return Leq(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Leq(Guid fieldId, int value)
		{
			return Leq(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Leq(Guid fieldId, double value)
		{
			return Leq(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Leq(Guid fieldId, bool value)
		{
			return Leq(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Leq(Guid fieldId, DateTime value)
		{
			return Leq(fieldId.ToString(), value);
		}

		#endregion

		#region GT

		public IQueryBuilderConditionGroup<TExecutorType> Gt(string field, string value)
		{
			return Condition(field, "GT", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Gt(string field, int value)
		{
			return Condition(field, "GT", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Gt(string field, double value)
		{
			return Condition(field, "GT", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Gt(string field, bool value)
		{
			return Condition(field, "GT", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Gt(string field, DateTime value)
		{
			return Condition(field, "GT", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Gt(Guid fieldId, string value)
		{
			return Gt(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Gt(Guid fieldId, int value)
		{
			return Gt(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Gt(Guid fieldId, double value)
		{
			return Gt(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Gt(Guid fieldId, bool value)
		{
			return Gt(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Gt(Guid fieldId, DateTime value)
		{
			return Gt(fieldId.ToString(), value);
		}

		#endregion

		#region LT

		public IQueryBuilderConditionGroup<TExecutorType> Lt(string field, string value)
		{
			return Condition(field, "LT", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Lt(string field, int value)
		{
			return Condition(field, "LT", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Lt(string field, double value)
		{
			return Condition(field, "LT", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Lt(string field, bool value)
		{
			return Condition(field, "LT", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Lt(string field, DateTime value)
		{
			return Condition(field, "LT", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Lt(Guid fieldId, string value)
		{
			return Lt(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Lt(Guid fieldId, int value)
		{
			return Lt(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Lt(Guid fieldId, double value)
		{
			return Lt(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Lt(Guid fieldId, bool value)
		{
			return Lt(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Lt(Guid fieldId, DateTime value)
		{
			return Lt(fieldId.ToString(), value);
		}

		#endregion

		#region In

		public IQueryBuilderConditionGroup<TExecutorType> In(string field, params int[] values)
		{
			AddItem(new CamlQueryBuilderInItem<TExecutorType>(field, "Integer", values.Select(value => value.ToString(H.En)).ToArray()));

			return this;
		}

		public IQueryBuilderConditionGroup<TExecutorType> In(string field, params double[] values)
		{
			AddItem(new CamlQueryBuilderInItem<TExecutorType>(field, "Number", values.Select(value => value.ToString(H.En.NumberFormat)).ToArray()));

			return this;
		}

		public IQueryBuilderConditionGroup<TExecutorType> In(string field, params bool[] values)
		{
			AddItem(new CamlQueryBuilderInItem<TExecutorType>(field, "Boolean", values.Select(value => (value ? "1" : "0")).ToArray()));

			return this;
		}

		public IQueryBuilderConditionGroup<TExecutorType> In(string field, params string[] values)
		{
			AddItem(new CamlQueryBuilderInItem<TExecutorType>(field, "Text", values));

			return this;
		}

		public IQueryBuilderConditionGroup<TExecutorType> In(string field, params DateTime[] values)
		{
			AddItem(new CamlQueryBuilderInItem<TExecutorType>(field, "DateTime", values.Select(value => SPUtility.CreateISO8601DateTimeFromSystemDateTime(value)).ToArray()));

			return this;
		}

		public IQueryBuilderConditionGroup<TExecutorType> In(Guid fieldId, params int[] values)
		{
			return In(fieldId.ToString(), values);
		}

		public IQueryBuilderConditionGroup<TExecutorType> In(Guid fieldId, params double[] values)
		{
			return In(fieldId.ToString(), values);
		}

		public IQueryBuilderConditionGroup<TExecutorType> In(Guid fieldId, params bool[] values)
		{
			return In(fieldId.ToString(), values);
		}

		public IQueryBuilderConditionGroup<TExecutorType> In(Guid fieldId, params string[] values)
		{
			return In(fieldId.ToString(), values);
		}

		public IQueryBuilderConditionGroup<TExecutorType> In(Guid fieldId, params DateTime[] values)
		{
			return In(fieldId.ToString(), values);
		}

		#endregion

		#region Additional text conditions

		public IQueryBuilderConditionGroup<TExecutorType> BeginsWith(string field, string value)
		{
			return Condition(field, "BeginsWith", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Contains(string field, string value)
		{
			return Condition(field, "Contains", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> BeginsWith(Guid fieldId, string value)
		{
			return BeginsWith(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Contains(Guid fieldId, string value)
		{
			return Contains(fieldId.ToString(), value);
		}

		#endregion

		#region Additional field conditions

		public IQueryBuilderConditionGroup<TExecutorType> IsNull(string field)
		{
			return Statement(field, "IsNull", string.Empty);
		}

		public IQueryBuilderConditionGroup<TExecutorType> IsNotNull(string field)
		{
			return Statement(field, "IsNotNull", string.Empty);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Membership(string field, MembershipType membership)
		{
			AddItem(new CamlQueryBuilderMembershipItem<TExecutorType>(field, membership));

			return this;
		}

		public IQueryBuilderConditionGroup<TExecutorType> IsNull(Guid fieldId)
		{
			return IsNull(fieldId.ToString());
		}

		public IQueryBuilderConditionGroup<TExecutorType> IsNotNull(Guid fieldId)
		{
			return IsNotNull(fieldId.ToString());
		}

		public IQueryBuilderConditionGroup<TExecutorType> Membership(Guid fieldId, MembershipType membership)
		{
			return Membership(fieldId.ToString(), membership);
		}

		#endregion

		#region Additional Lookup conditions

		public IQueryBuilderConditionGroup<TExecutorType> EqL(string field, int value)
		{
			AddItem(new CamlQueryBuilderStatementItem<TExecutorType>(field, " LookupId=\"TRUE\"", "Eq", "<Value Type=\"Lookup\">" + value.ToString(H.En) + "</Value>"));

			return this;
		}

		public IQueryBuilderConditionGroup<TExecutorType> NeqL(string field, int value)
		{
			AddItem(new CamlQueryBuilderStatementItem<TExecutorType>(field, " LookupId=\"TRUE\"", "Neq", "<Value Type=\"Lookup\">" + value.ToString(H.En) + "</Value>"));

			return this;
		}

		public IQueryBuilderConditionGroup<TExecutorType> Includes(string field, int value)
		{
			AddItem(new CamlQueryBuilderStatementItem<TExecutorType>(field, " LookupId=\"TRUE\"", "Includes", "<Value Type=\"Lookup\">" + value.ToString(H.En) + "</Value>"));

			return this;
		}

		public IQueryBuilderConditionGroup<TExecutorType> NotIncludes(string field, int value)
		{
			AddItem(new CamlQueryBuilderStatementItem<TExecutorType>(field, " LookupId=\"TRUE\"", "NotIncludes", "<Value Type=\"Lookup\">" + value.ToString(H.En) + "</Value>"));

			return this;
		}

		public IQueryBuilderConditionGroup<TExecutorType> Includes(string field, string value)
		{
			return Condition(field, "Includes", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> NotIncludes(string field, string value)
		{
			return Condition(field, "NotIncludes", value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> EqU(string field, SPUser value)
		{
			return EqL(field, value.ID);
		}

		public IQueryBuilderConditionGroup<TExecutorType> EqU(string field, int userId)
		{
			return EqL(field, userId);
		}

		public IQueryBuilderConditionGroup<TExecutorType> NeqU(string field, SPUser value)
		{
			return NeqL(field, value.ID);
		}

		public IQueryBuilderConditionGroup<TExecutorType> NeqU(string field, int userId)
		{
			return NeqL(field, userId);
		}

		public IQueryBuilderConditionGroup<TExecutorType> IncludesU(string field, SPUser value)
		{
			return Includes(field, value.ID);
		}

		public IQueryBuilderConditionGroup<TExecutorType> IncludesU(string field, int userId)
		{
			return Includes(field, userId);
		}

		public IQueryBuilderConditionGroup<TExecutorType> NotIncludesU(string field, SPUser value)
		{
			return NotIncludes(field, value.ID);
		}

		public IQueryBuilderConditionGroup<TExecutorType> NotIncludesU(string field, int userId)
		{
			return NotIncludes(field, userId);
		}

		public IQueryBuilderConditionGroup<TExecutorType> EqU(string field)
		{
			AddItem(new CamlQueryBuilderStatementItem<TExecutorType>(field, null, "Eq", "<Value Type=\"Integer\"><UserID Type=\"Integer\"/></Value>"));

			return this;
		}

		public IQueryBuilderConditionGroup<TExecutorType> NeqU(string field)
		{
			AddItem(new CamlQueryBuilderStatementItem<TExecutorType>(field, null, "Neq", "<Value Type=\"Integer\"><UserID Type=\"Integer\"/></Value>"));

			return this;
		}

		public IQueryBuilderConditionGroup<TExecutorType> IncludesU(string field)
		{
			AddItem(new CamlQueryBuilderStatementItem<TExecutorType>(field, null, "Includes", "<Value Type=\"Integer\"><UserID Type=\"Integer\"/></Value>"));

			return this;
		}

		public IQueryBuilderConditionGroup<TExecutorType> NotIncludesU(string field)
		{
			AddItem(new CamlQueryBuilderStatementItem<TExecutorType>(field, null, "NotIncludes", "<Value Type=\"Integer\"><UserID Type=\"Integer\"/></Value>"));

			return this;
		}

		public IQueryBuilderConditionGroup<TExecutorType> EqL(Guid fieldId, int value)
		{
			return EqL(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> NeqL(Guid fieldId, int value)
		{
			return NeqL(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Includes(Guid fieldId, int value)
		{
			return Includes(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> NotIncludes(Guid fieldId, int value)
		{
			return NotIncludes(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Includes(Guid fieldId, string value)
		{
			return Includes(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> NotIncludes(Guid fieldId, string value)
		{
			return NotIncludes(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> EqU(Guid fieldId, SPUser value)
		{
			return EqU(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> EqU(Guid fieldId, int userId)
		{
			return EqU(fieldId.ToString(), userId);
		}

		public IQueryBuilderConditionGroup<TExecutorType> NeqU(Guid fieldId, SPUser value)
		{
			return NeqU(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> NeqU(Guid fieldId, int userId)
		{
			return NeqU(fieldId.ToString(), userId);
		}

		public IQueryBuilderConditionGroup<TExecutorType> IncludesU(Guid fieldId, SPUser value)
		{
			return IncludesU(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> IncludesU(Guid fieldId, int userId)
		{
			return IncludesU(fieldId.ToString(), userId);
		}

		public IQueryBuilderConditionGroup<TExecutorType> NotIncludesU(Guid fieldId, SPUser value)
		{
			return NotIncludesU(fieldId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> NotIncludesU(Guid fieldId, int userId)
		{
			return NotIncludesU(fieldId.ToString(), userId);
		}

		public IQueryBuilderConditionGroup<TExecutorType> EqU(Guid fieldId)
		{
			return EqU(fieldId.ToString());
		}

		public IQueryBuilderConditionGroup<TExecutorType> NeqU(Guid fieldId)
		{
			return NeqU(fieldId.ToString());
		}

		public IQueryBuilderConditionGroup<TExecutorType> IncludesU(Guid fieldId)
		{
			return IncludesU(fieldId.ToString());
		}

		public IQueryBuilderConditionGroup<TExecutorType> NotIncludesU(Guid fieldId)
		{
			return NotIncludesU(fieldId.ToString());
		}

		#endregion

		#region Additional DateTime conditions

		public IQueryBuilderConditionGroup<TExecutorType> DateRangesOverlap(string fieldStartDate, string fieldEndDate, string fieldRecurrenceId, DateTime value, bool includeTimeValue)
		{
			AddItem(new CamlQueryBuilderDateRangesOverlapItem<TExecutorType>(fieldStartDate, fieldEndDate, fieldRecurrenceId, includeTimeValue, value));

			return this;
		}

		public IQueryBuilderConditionGroup<TExecutorType> DateRangesOverlap(string fieldStartDate, string fieldEndDate, string fieldRecurrenceId, DateRangesOverlapValue value)
		{
			AddItem(new CamlQueryBuilderDateRangesOverlapItem<TExecutorType>(fieldStartDate, fieldEndDate, fieldRecurrenceId, value.ToString()));

			return this;
		}

		public IQueryBuilderConditionGroup<TExecutorType> Eq(string field, DateTime value, bool includeTimeValue)
		{
			return Statement(field, "Eq",
							 "<Value Type=\"DateTime\" IncludeTimeValue=\"" + (includeTimeValue ? "TRUE" : "FALSE") + "\">" + SPUtility.CreateISO8601DateTimeFromSystemDateTime(value) +
							 "</Value>");
		}

		public IQueryBuilderConditionGroup<TExecutorType> Neq(string field, DateTime value, bool includeTimeValue)
		{
			return Statement(field, "Neq",
							 "<Value Type=\"DateTime\" IncludeTimeValue=\"" + (includeTimeValue ? "TRUE" : "FALSE") + "\">" + SPUtility.CreateISO8601DateTimeFromSystemDateTime(value) +
							 "</Value>");
		}

		public IQueryBuilderConditionGroup<TExecutorType> Geq(string field, DateTime value, bool includeTimeValue)
		{
			return Statement(field, "Geq",
							 "<Value Type=\"DateTime\" IncludeTimeValue=\"" + (includeTimeValue ? "TRUE" : "FALSE") + "\">" + SPUtility.CreateISO8601DateTimeFromSystemDateTime(value) +
							 "</Value>");
		}

		public IQueryBuilderConditionGroup<TExecutorType> Leq(string field, DateTime value, bool includeTimeValue)
		{
			return Statement(field, "Leq",
							 "<Value Type=\"DateTime\" IncludeTimeValue=\"" + (includeTimeValue ? "TRUE" : "FALSE") + "\">" + SPUtility.CreateISO8601DateTimeFromSystemDateTime(value) +
							 "</Value>");
		}

		public IQueryBuilderConditionGroup<TExecutorType> Gt(string field, DateTime value, bool includeTimeValue)
		{
			return Statement(field, "Gt",
							 "<Value Type=\"DateTime\" IncludeTimeValue=\"" + (includeTimeValue ? "TRUE" : "FALSE") + "\">" + SPUtility.CreateISO8601DateTimeFromSystemDateTime(value) +
							 "</Value>");
		}

		public IQueryBuilderConditionGroup<TExecutorType> Lt(string field, DateTime value, bool includeTimeValue)
		{
			return Statement(field, "Lt",
							 "<Value Type=\"DateTime\" IncludeTimeValue=\"" + (includeTimeValue ? "TRUE" : "FALSE") + "\">" + SPUtility.CreateISO8601DateTimeFromSystemDateTime(value) +
							 "</Value>");
		}

		public IQueryBuilderConditionGroup<TExecutorType> DateRangesOverlap(Guid fieldIdStartDate, Guid fieldIdEndDate, Guid fieldIdRecurrenceId, DateTime value, bool includeTimeValue)
		{
			return DateRangesOverlap(fieldIdStartDate.ToString(), fieldIdEndDate.ToString(), fieldIdRecurrenceId.ToString(), value, includeTimeValue);
		}

		public IQueryBuilderConditionGroup<TExecutorType> DateRangesOverlap(Guid fieldIdStartDate, Guid fieldIdEndDate, Guid fieldIdRecurrenceId, DateRangesOverlapValue value)
		{
			return DateRangesOverlap(fieldIdStartDate.ToString(), fieldIdEndDate.ToString(), fieldIdRecurrenceId.ToString(), value);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Eq(Guid fieldId, DateTime value, bool includeTimeValue)
		{
			return Eq(fieldId.ToString(), value, includeTimeValue);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Neq(Guid fieldId, DateTime value, bool includeTimeValue)
		{
			return Neq(fieldId.ToString(), value, includeTimeValue);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Geq(Guid fieldId, DateTime value, bool includeTimeValue)
		{
			return Geq(fieldId.ToString(), value, includeTimeValue);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Leq(Guid fieldId, DateTime value, bool includeTimeValue)
		{
			return Leq(fieldId.ToString(), value, includeTimeValue);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Gt(Guid fieldId, DateTime value, bool includeTimeValue)
		{
			return Gt(fieldId.ToString(), value, includeTimeValue);
		}

		public IQueryBuilderConditionGroup<TExecutorType> Lt(Guid fieldId, DateTime value, bool includeTimeValue)
		{
			return Lt(fieldId.ToString(), value, includeTimeValue);
		}

		#endregion

		#region Group conditions

		//public IQueryBuilderConditionGroup<TExecutorType> And(IEnumerable<CamlQueryBuilderItem<TExecutorType>> items)
		//{
		//    var and = new CamlQueryBuilderAnd<TExecutorType>();
		//    AddItem(and);
		//    and.AddItems(items);
		//    return this;
		//}

		//public IQueryBuilderConditionGroup<TExecutorType> Or(IEnumerable<CamlQueryBuilderItem<TExecutorType>> items)
		//{
		//    var or = new CamlQueryBuilderOr<TExecutorType>();
		//    AddItem(or);
		//    or.AddItems(items);
		//    return this;
		//}

		public IQueryBuilderConditionGroup<TExecutorType> And
		{
			get
			{
				var and = new CamlQueryBuilderAnd<TExecutorType>();

				AddItem(and);

				return and;
			}
		}

		public IQueryBuilderConditionGroup<TExecutorType> Or
		{
			get
			{
				var or = new CamlQueryBuilderOr<TExecutorType>();

				AddItem(or);

				return or;
			}
		}

		public IQueryBuilderConditionGroup<TExecutorType> End
		{
			get { return Parent; }
		}

		public bool IsDateRangesOverlapUsed
		{
			get { return FindRecursive("DateRangesOverlap").Count > 0; }
		}

		#endregion
	}
}